<?php

namespace lc\wechat\qywx;

use lc\cache\redis\Redis;
use lc\helpers\Curl;
use lc\helpers\Helper;
use think\facade\Config;
use think\facade\Db;

class Oauth
{
    private static $corpId;
    private static $agentId;
    private static $agentSecret;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->config = Config::get('lc.qywx');

        self::$corpId       = $this->config['corpId'];
        self::$agentId      = $this->config['agentId'];
        self::$agentSecret  = $this->config['agentSecret'];
    }

    /**
     * @desc    应用ID
     * @return  mixed
     */
    public function getAgentId()
    {
        return self::$agentId;
    }

    /**
     * @desc    企业微信授权
     * @param   string  $redirectUrl
     */
    public function oauth(string $redirectUrl)
    {
        $corpId  = self::$corpId;
        $agentId = self::$agentId;
        $redirect= urlencode($redirectUrl);
        if (Helper::isWeixin()) {
            $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$corpId}&redirect_uri={$redirect}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
        } else {
            // 浏览器打开，扫码登录
            $url = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid={$corpId}&agentid={$agentId}&redirect_uri={$redirect}&state=STATE";
        }

        if (Helper::deviceType() === 'ios') {
            header("Location:" . $url);
        } else {
            echo "<script>window.open('$url', '_self');</script>";
        }
        exit();
    }

    /**
     * @desc    获取用户信息
     * @param   string  $code
     * @return  array
     */
    public function userId(string $code)
    {
        $accessToken = $this->accessToken();
        $url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={$accessToken}&code={$code}";

        $response = Curl::requestCurl($url, 'GET', []);
        $response = json_decode($response, true);
        if (isset($response['errcode']) && $response['errcode'] == 0) {
            return $response;
        } else {
            return [];
        }
    }

    /**
     * 获取用户详情
     *
     * @param $userId
     * @return array
     * @throws \Exception
     */
    public function userDetailInfo(string $userId)
    {
        $accessToken = $this->accessToken();
        $url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={$accessToken}&userid={$userId}";

        $response = Curl::requestCurl($url, 'GET', []);
        $response = json_decode($response, true);
        if (isset($response['errcode']) && $response['errcode'] == 0) {
            return $response;
        } else {
            return [];
        }
    }

    /**
     * 获取部门信息
     *
     * @param int $departmentId
     * @return array|mixed
     * @throws \Exception
     */
    public function getDepartmentList(int $departmentId)
    {
        $accessToken = $this->accessToken();
        $url = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={$accessToken}&id={$departmentId}";

        $response = Curl::requestCurl($url, 'GET', []);
        $response = json_decode($response, true);
        if (isset($response['errcode']) && $response['errcode'] == 0) {
            return $response;
        } else {
            return [];
        }
    }

    /**
     * @desc    获取access_token
     * @param   int $repeatCnt
     * @return  string
     */
    public function accessToken(&$repeatCnt = 1)
    {
        $drive = $this->config['token_drive'] ?? 'redis';
        $key   = 'qywx_' . self::$agentId . '_accessToken';
        switch ($drive) {
            case 'redis':
                $redis = Redis::instance();
                $redis->select(15);

                $token = $redis->get($key);
                break;
            case 'db':
            default:
                $token = Db::connect('main')->name('configs')->where('c_key', $key)->where('c_expired > ' . time())->value('c_value');
                break;
        }
        if ($token) {
            return $token;
        }

        $url      = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" . self::$corpId . "&corpsecret=" . self::$agentSecret;
        $response = Curl::requestCurl($url, 'GET', []);
        $response = json_decode($response, true);
        if (isset($response['access_token'])) {
            $token = $response['access_token'];
            switch ($drive) {
                case 'redis':
                    $redis->setex($key, 7000, $token);
                    break;
                case 'db':
                default:
                    Db::connect('main')
                        ->name('configs')
                        ->where('c_key', $key)
                        ->update([
                            'c_value'   => $token,
                            'c_expired' => time() + 7000,
                            'c_updated' => date('Y-m-d H:i:s')
                        ]);
                    break;
            }

            return $token;
        } else {
            if ($repeatCnt <= 3) {
                $repeatCnt++;
                return $this->accessToken($repeatCnt);
            } else {
                return '';
            }
        }
    }
}